home *** CD-ROM | disk | FTP | other *** search
/ STraTOS 1997 April & May / STraTOS 1 - 1997 April & May.iso / CD01 / INTERNET / SITES / LITTLE / P3SRC.ZIP / ATARI / CHI2.C < prev    next >
Encoding:
C/C++ Source or Header  |  1997-01-18  |  19.2 KB  |  1,017 lines

  1. /****************************************************************************
  2. *                   chi2.c
  3. *
  4. *  This module contains the function for the chi square distribution.
  5. *
  6. *  All functions in this module are taken from the Cephes math library.
  7. *
  8. *    Cephes Math Library Release 2.0:  April, 1987
  9. *    Copyright 1984, 1987 by Stephen L. Moshier
  10. *    Direct inquiries to 30 Frost Street, Cambridge, MA 02140
  11. *
  12. *  from Persistence of Vision(tm) Ray Tracer
  13. *  Copyright 1996 Persistence of Vision Team
  14. *---------------------------------------------------------------------------
  15. *  NOTICE: This source code file is provided so that users may experiment
  16. *  with enhancements to POV-Ray and to port the software to platforms other
  17. *  than those supported by the POV-Ray Team.  There are strict rules under
  18. *  which you are permitted to use this file.  The rules are in the file
  19. *  named POVLEGAL.DOC which should be distributed with this file. If
  20. *  POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  21. *  Team Coordinator by leaving a message in CompuServe's Graphics Developer's
  22. *  Forum.  The latest version of POV-Ray may be found there as well.
  23. *
  24. * This program is based on the popular DKB raytracer version 2.12.
  25. * DKBTrace was originally written by David K. Buck.
  26. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  27. *
  28. *****************************************************************************/
  29.  
  30. #include "frame.h"
  31. #include "povproto.h"
  32. #include "chi2.h"
  33.  
  34. /*
  35. Cephes Math Library Release 2.0:  April, 1987
  36. Copyright 1984, 1987 by Stephen L. Moshier
  37. Direct inquiries to 30 Frost Street, Cambridge, MA 02140
  38. */
  39.  
  40. /*****************************************************************************
  41. * Local preprocessor defines
  42. ******************************************************************************/
  43.  
  44. #define MAXLGM 2.556348e305
  45. #define BIG    1.44115188075855872E+17
  46. #define MACHEP 1.38777878078144567553E-17 /* 2**-56 */
  47. #define MAXLOG 8.8029691931113054295988E1 /* log(2**127) */
  48. #define MAXNUM 1.701411834604692317316873e38  /* 2**127 */
  49. #define LOGPI 1.14472988584940017414
  50.  
  51.  
  52.  
  53. /*****************************************************************************
  54. * Local typedefs
  55. ******************************************************************************/
  56.  
  57.  
  58.  
  59. /*****************************************************************************
  60. * Local variables
  61. ******************************************************************************/
  62.  
  63. static int sgngam = 0;
  64.  
  65. /*
  66.  * A[]: Stirling's formula expansion of log gamma
  67.  * B[], C[]: log gamma function between 2 and 3
  68.  */
  69.  
  70. static DBL A[] =
  71. {
  72.    8.11614167470508450300E-4,
  73.   -5.95061904284301438324E-4,
  74.    7.93650340457716943945E-4,
  75.   -2.77777777730099687205E-3,
  76.    8.33333333333331927722E-2
  77. };
  78.  
  79. static DBL B[] =
  80. {
  81.   -1.37825152569120859100E3,
  82.   -3.88016315134637840924E4,
  83.   -3.31612992738871184744E5,
  84.   -1.16237097492762307383E6,
  85.   -1.72173700820839662146E6,
  86.   -8.53555664245765465627E5
  87. };
  88.  
  89. static DBL C[] =
  90. {
  91.    1.00000000000000000000E0,
  92.   -3.51815701436523470549E2,
  93.   -1.70642106651881159223E4,
  94.   -2.20528590553854454839E5,
  95.   -1.13933444367982507207E6,
  96.   -2.53252307177582951285E6,
  97.   -2.01889141433532773231E6
  98. };
  99.  
  100. /* log(sqrt(2pi)) */
  101.  
  102. static DBL LS2PI = 0.91893853320467274178;
  103.  
  104. /* sqrt(2pi) */
  105.  
  106. static DBL s2pi = 2.50662827463100050242E0;
  107.  
  108. /* approximation for 0 <= |y - 0.5| <= 3/8 */
  109.  
  110. static DBL P0[5] =
  111. {
  112.   -5.99633501014107895267E1,
  113.    9.80010754185999661536E1,
  114.   -5.66762857469070293439E1,
  115.    1.39312609387279679503E1,
  116.   -1.23916583867381258016E0,
  117. };
  118.  
  119. static DBL Q0[8] =
  120. {
  121. /* 1.00000000000000000000E0,*/
  122.    1.95448858338141759834E0,
  123.    4.67627912898881538453E0,
  124.    8.63602421390890590575E1,
  125.   -2.25462687854119370527E2,
  126.    2.00260212380060660359E2,
  127.   -8.20372256168333339912E1,
  128.    1.59056225126211695515E1,
  129.   -1.18331621121330003142E0,
  130. };
  131.  
  132. /*
  133.  * Approximation for interval z = sqrt(-2 log y ) between 2 and 8
  134.  * i.e., y between exp(-2) = .135 and exp(-32) = 1.27e-14.
  135.  */
  136.  
  137. static DBL P1[9] =
  138. {
  139.    4.05544892305962419923E0,
  140.    3.15251094599893866154E1,
  141.    5.71628192246421288162E1,
  142.    4.40805073893200834700E1,
  143.    1.46849561928858024014E1,
  144.    2.18663306850790267539E0,
  145.   -1.40256079171354495875E-1,
  146.   -3.50424626827848203418E-2,
  147.   -8.57456785154685413611E-4,
  148. };
  149.  
  150. static DBL Q1[8] =
  151. {
  152. /*  1.00000000000000000000E0,*/
  153.    1.57799883256466749731E1,
  154.    4.53907635128879210584E1,
  155.    4.13172038254672030440E1,
  156.    1.50425385692907503408E1,
  157.    2.50464946208309415979E0,
  158.   -1.42182922854787788574E-1,
  159.   -3.80806407691578277194E-2,
  160.   -9.33259480895457427372E-4,
  161. };
  162.  
  163. /*
  164.  * Approximation for interval z = sqrt(-2 log y ) between 8 and 64
  165.  * i.e., y between exp(-32) = 1.27e-14 and exp(-2048) = 3.67e-890.
  166.  */
  167.  
  168. static DBL P2[9] =
  169. {
  170.   3.23774891776946035970E0,
  171.   6.91522889068984211695E0,
  172.   3.93881025292474443415E0,
  173.   1.33303460815807542389E0,
  174.   2.01485389549179081538E-1,
  175.   1.23716634817820021358E-2,
  176.   3.01581553508235416007E-4,
  177.   2.65806974686737550832E-6,
  178.   6.23974539184983293730E-9,
  179. };
  180.  
  181. static DBL Q2[8] =
  182. {
  183. /*  1.00000000000000000000E0,*/
  184.   6.02427039364742014255E0,
  185.   3.67983563856160859403E0,
  186.   1.37702099489081330271E0,
  187.   2.16236993594496635890E-1,
  188.   1.34204006088543189037E-2,
  189.   3.28014464682127739104E-4,
  190.   2.89247864745380683936E-6,
  191.   6.79019408009981274425E-9,
  192. };
  193.  
  194.  
  195. /*****************************************************************************
  196. * Static functions
  197. ******************************************************************************/
  198.  
  199. static DBL igami PARAMS((DBL a, DBL y0));
  200. static DBL lgam PARAMS((DBL x));
  201. static DBL polevl PARAMS((DBL x, DBL * coef, int N));
  202. static DBL p1evl PARAMS((DBL x, DBL * coef, int N));
  203. static DBL igamc PARAMS((DBL a, DBL x));
  204. static DBL igam PARAMS((DBL a, DBL x));
  205. static DBL ndtri PARAMS((DBL y0));
  206.  
  207.  
  208.  
  209. /*              chdtri()
  210.  *
  211.  *  Inverse of complemented Chi-square distribution
  212.  *
  213.  *
  214.  *
  215.  * SYNOPSIS:
  216.  *
  217.  * DBL df, x, y, chdtri();
  218.  *
  219.  * x = chdtri( df, y );
  220.  *
  221.  *
  222.  *
  223.  *
  224.  * DESCRIPTION:
  225.  *
  226.  * Finds the Chi-square argument x such that the integral
  227.  * from x to infinity of the Chi-square density is equal
  228.  * to the given cumulative probability y.
  229.  *
  230.  * This is accomplished using the inverse gamma integral
  231.  * function and the relation
  232.  *
  233.  *    x/2 = igami( df/2, y );
  234.  *
  235.  *
  236.  *
  237.  *
  238.  * ACCURACY:
  239.  *
  240.  * See igami.c.
  241.  *
  242.  * ERROR MESSAGES:
  243.  *
  244.  *   message         condition      value returned
  245.  * chdtri domain   y < 0 or y > 1        0.0
  246.  *                     v < 1
  247.  *
  248.  */
  249.  
  250. DBL chdtri(df, y)
  251. DBL df, y;
  252. {
  253.   DBL x;
  254.  
  255.   if ((y < 0.0) || (y > 1.0) || (df < 1.0))
  256.   {
  257.     Error("Illegal values fd=%f and y=%f in chdtri().\n", df, y);
  258.  
  259.     return (0.0);
  260.   }
  261.  
  262.   x = igami(0.5 * df, y);
  263.  
  264.   return (2.0 * x);
  265. }
  266.  
  267.  
  268.  
  269. /*              lgam()
  270.  *
  271.  *  Natural logarithm of gamma function
  272.  *
  273.  *
  274.  *
  275.  * SYNOPSIS:
  276.  *
  277.  * DBL x, y, lgam();
  278.  * extern int sgngam;
  279.  *
  280.  * y = lgam( x );
  281.  *
  282.  *
  283.  *
  284.  * DESCRIPTION:
  285.  *
  286.  * Returns the base e (2.718...) logarithm of the absolute
  287.  * value of the gamma function of the argument.
  288.  * The sign (+1 or -1) of the gamma function is returned in a
  289.  * global (extern) variable named sgngam.
  290.  *
  291.  * For arguments greater than 13, the logarithm of the gamma
  292.  * function is approximated by the logarithmic version of
  293.  * Stirling's formula using a polynomial approximation of
  294.  * degree 4. Arguments between -33 and +33 are reduced by
  295.  * recurrence to the interval [2,3] of a rational approximation.
  296.  * The cosecant reflection formula is employed for arguments
  297.  * less than -33.
  298.  *
  299.  * Arguments greater than MAXLGM return MAXNUM and an error
  300.  * message.  MAXLGM = 2.035093e36 for DEC
  301.  * arithmetic or 2.556348e305 for IEEE arithmetic.
  302.  *
  303.  *
  304.  *
  305.  * ACCURACY:
  306.  *
  307.  *
  308.  * arithmetic      domain        # trials     peak         rms
  309.  *    DEC     0, 3                  7000     5.2e-17     1.3e-17
  310.  *    DEC     2.718, 2.035e36       5000     3.9e-17     9.9e-18
  311.  *    IEEE    0, 3                 28000     5.4e-16     1.1e-16
  312.  *    IEEE    2.718, 2.556e305     40000     3.5e-16     8.3e-17
  313.  * The error criterion was relative when the function magnitude
  314.  * was greater than one but absolute when it was less than one.
  315.  *
  316.  * The following test used the relative error criterion, though
  317.  * at certain points the relative error could be much higher than
  318.  * indicated.
  319.  *    IEEE    -200, -4             10000     4.8e-16     1.3e-16
  320.  *
  321.  */
  322.  
  323. static DBL lgam(x)
  324. DBL x;
  325. {
  326.   DBL p, q, w, z;
  327.   int i;
  328.  
  329.   sgngam = 1;
  330.  
  331.   if (x < -34.0)
  332.   {
  333.     q = -x;
  334.     w = lgam(q);  /* note this modifies sgngam! */
  335.     p = floor(q);
  336.  
  337.     if (p == q)
  338.     {
  339.       goto loverf;
  340.     }
  341.  
  342.     i = p;
  343.  
  344.     if ((i & 1) == 0)
  345.     {
  346.       sgngam = -1;
  347.     }
  348.     else
  349.     {
  350.       sgngam = 1;
  351.     }
  352.  
  353.     z = q - p;
  354.  
  355.     if (z > 0.5)
  356.     {
  357.       p += 1.0;
  358.  
  359.       z = p - q;
  360.     }
  361.  
  362.     z = q * sin(M_PI * z);
  363.  
  364.     if (z == 0.0)
  365.     {
  366.       goto loverf;
  367.     }
  368.  
  369. /*  z = log(PI) - log( z ) - w;*/
  370.  
  371.     z = LOGPI - log(z) - w;
  372.  
  373.     return (z);
  374.   }
  375.  
  376.   if (x < 13.0)
  377.   {
  378.     z = 1.0;
  379.  
  380.     while (x >= 3.0)
  381.     {
  382.       x -= 1.0;
  383.  
  384.       z *= x;
  385.     }
  386.  
  387.     while (x < 2.0)
  388.     {
  389.       if (x == 0.0)
  390.       {
  391.         goto loverf;
  392.       }
  393.  
  394.       z /= x;
  395.  
  396.       x += 1.0;
  397.     }
  398.  
  399.     if (z < 0.0)
  400.     {
  401.       sgngam = -1;
  402.  
  403.       z = -z;
  404.     }
  405.     else
  406.     {
  407.       sgngam = 1;
  408.     }
  409.  
  410.     if (x == 2.0)
  411.     {
  412.       return (log(z));
  413.     }
  414.  
  415.     x -= 2.0;
  416.  
  417.     p = x * polevl(x, B, 5) / p1evl(x, C, 6);
  418.  
  419.     return (log(z) + p);
  420.   }
  421.  
  422.   if (x > MAXLGM)
  423.   {
  424.     loverf:
  425. /*
  426.     mtherr("lgam", OVERFLOW);
  427. */
  428.     return (sgngam * MAXNUM);
  429.   }
  430.  
  431.   q = (x - 0.5) * log(x) - x + LS2PI;
  432.  
  433.   if (x > 1.0e8)
  434.   {
  435.     return (q);
  436.   }
  437.  
  438.   p = 1.0 / (x * x);
  439.  
  440.   if (x >= 1000.0)
  441.   {
  442.     q += ((7.9365079365079365079365e-4 * p -
  443.            2.7777777777777777777778e-3) * p +
  444.            0.0833333333333333333333) / x;
  445.   }
  446.   else
  447.   {
  448.     q += polevl(p, A, 4) / x;
  449.   }
  450.  
  451.   return (q);
  452. }
  453.  
  454.  
  455.  
  456. /*              igamc()
  457.  *
  458.  *  Complemented incomplete gamma integral
  459.  *
  460.  *
  461.  *
  462.  * SYNOPSIS:
  463.  *
  464.  * DBL a, x, y, igamc();
  465.  *
  466.  * y = igamc( a, x );
  467.  *
  468.  *
  469.  *
  470.  * DESCRIPTION:
  471.  *
  472.  * The function is defined by
  473.  *
  474.  *
  475.  *  igamc(a,x)   =   1 - igam(a,x)
  476.  *
  477.  *                            inf.
  478.  *                              -
  479.  *                     1       | |  -t  a-1
  480.  *               =   -----     |   e   t   dt.
  481.  *                    -      | |
  482.  *                   | (a)    -
  483.  *                             x
  484.  *
  485.  *
  486.  * In this implementation both arguments must be positive.
  487.  * The integral is evaluated by either a power series or
  488.  * continued fraction expansion, depending on the relative
  489.  * values of a and x.
  490.  *
  491.  *
  492.  *
  493.  * ACCURACY:
  494.  *
  495.  *                      Relative error:
  496.  * arithmetic   domain     # trials      peak         rms
  497.  *    DEC       0,30         2000       2.7e-15     4.0e-16
  498.  *    IEEE      0,30        60000       1.4e-12     6.3e-15
  499.  *
  500.  */
  501.  
  502. static DBL igamc(a, x)
  503. DBL a, x;
  504. {
  505.   DBL ans, c, yc, ax, y, z;
  506.   DBL pk, pkm1, pkm2, qk, qkm1, qkm2;
  507.   DBL r, t;
  508.   DBL rdiv;
  509.   
  510.   if ((x <= 0) || (a <= 0))
  511.   {
  512.     return (1.0);
  513.   }
  514.  
  515.   if ((x < 1.0) || (x < a))
  516.   {
  517.     return (1.0 - igam(a, x));
  518.   }
  519.  
  520.   ax = a * log(x) - x - lgam(a);
  521.  
  522.   if (ax < -MAXLOG)
  523.   {
  524. /*
  525.     mtherr("igamc", UNDERFLOW);
  526. */
  527.     return (0.0);
  528.   }
  529.  
  530.   ax = exp(ax);
  531.  
  532. /* continued fraction */
  533.  
  534.   y = 1.0 - a;
  535.   z = x + y + 1.0;
  536.   c = 0.0;
  537.  
  538.   pkm2 = 1.0;
  539.   qkm2 = x;
  540.   pkm1 = x + 1.0;
  541.   qkm1 = z * x;
  542.  
  543.   ans = pkm1 / qkm1;
  544.  
  545.   do
  546.   {
  547.     c += 1.0;
  548.     y += 1.0;
  549.     z += 2.0;
  550.  
  551.     yc = y * c;
  552.  
  553.     pk = pkm1 * z - pkm2 * yc;
  554.     qk = qkm1 * z - qkm2 * yc;
  555.  
  556.     if (qk != 0)
  557.     {
  558.       r = pk / qk;
  559.       t = fabs((ans - r) / r);
  560.       ans = r;
  561.     }
  562.     else
  563.     {
  564.       t = 1.0;
  565.     }
  566.  
  567.     pkm2 = pkm1;
  568.     pkm1 = pk;
  569.     qkm2 = qkm1;
  570.     qkm1 = qk;
  571.  
  572.     if (fabs(pk) > BIG)
  573.     {
  574. /*
  575.       pkm2 /= BIG;
  576.       pkm1 /= BIG;
  577.       qkm2 /= BIG;
  578.       qkm1 /= BIG;
  579. */
  580.       rdiv = (1.0 / BIG);
  581.       pkm2 *= rdiv;
  582.       pkm1 *= rdiv;
  583.       qkm2 *= rdiv;
  584.       qkm1 *= rdiv;
  585.     }
  586.   }
  587.   while (t > MACHEP);
  588.  
  589.   return (ans * ax);
  590. }
  591.  
  592.  
  593.  
  594. /*              igam.c
  595.  *
  596.  *  Incomplete gamma integral
  597.  *
  598.  *
  599.  *
  600.  * SYNOPSIS:
  601.  *
  602.  * DBL a, x, y, igam();
  603.  *
  604.  * y = igam( a, x );
  605.  *
  606.  *
  607.  *
  608.  * DESCRIPTION:
  609.  *
  610.  * The function is defined by
  611.  *
  612.  *                           x
  613.  *                            -
  614.  *                   1       | |  -t  a-1
  615.  *  igam(a,x)  =   -----     |   e   t   dt.
  616.  *                  -      | |
  617.  *                 | (a)    -
  618.  *                           0
  619.  *
  620.  *
  621.  * In this implementation both arguments must be positive.
  622.  * The integral is evaluated by either a power series or
  623.  * continued fraction expansion, depending on the relative
  624.  * values of a and x.
  625.  *
  626.  *
  627.  *
  628.  * ACCURACY:
  629.  *
  630.  *                      Relative error:
  631.  * arithmetic   domain     # trials      peak         rms
  632.  *    DEC       0,30         4000       4.4e-15     6.3e-16
  633.  *    IEEE      0,30        10000       3.6e-14     5.1e-15
  634.  *
  635.  */
  636.  
  637. /* left tail of incomplete gamma function:
  638.  *
  639.  *          inf.      k
  640.  *   a  -x   -       x
  641.  *  x  e     >   ----------
  642.  *           -     -
  643.  *          k=0   | (a+k+1)
  644.  *
  645.  */
  646.  
  647. static DBL igam(a, x)
  648. DBL a, x;
  649. {
  650.   DBL ans, ax, c, r;
  651.  
  652.   if ((x <= 0) || (a <= 0))
  653.   {
  654.     return (0.0);
  655.   }
  656.  
  657.   if ((x > 1.0) && (x > a))
  658.   {
  659.     return (1.0 - igamc(a, x));
  660.   }
  661.  
  662. /* Compute  x**a * exp(-x) / gamma(a)  */
  663.   ax = a * log(x) - x - lgam(a);
  664.  
  665.   if (ax < -MAXLOG)
  666.   {
  667. /*
  668.     mtherr("igam", UNDERFLOW);
  669. */
  670.     return (0.0);
  671.   }
  672.  
  673.   ax = exp(ax);
  674.  
  675. /* power series */
  676.   r = a;
  677.   c = 1.0;
  678.   ans = 1.0;
  679.  
  680.   do
  681.   {
  682.     r += 1.0;
  683.     c *= x / r;
  684.     ans += c;
  685.   }
  686.   while (c / ans > MACHEP);
  687.  
  688.   return (ans * ax / a);
  689. }
  690.  
  691.  
  692.  
  693. /*              igami()
  694.  *
  695.  *      Inverse of complemented imcomplete gamma integral
  696.  *
  697.  *
  698.  *
  699.  * SYNOPSIS:
  700.  *
  701.  * DBL a, x, y, igami();
  702.  *
  703.  * x = igami( a, y );
  704.  *
  705.  *
  706.  *
  707.  * DESCRIPTION:
  708.  *
  709.  * Given y, the function finds x such that
  710.  *
  711.  *  igamc( a, x ) = y.
  712.  *
  713.  * Starting with the approximate value
  714.  *
  715.  *         3
  716.  *  x = a t
  717.  *
  718.  *  where
  719.  *
  720.  *  t = 1 - d - ndtri(y) sqrt(d)
  721.  *
  722.  * and
  723.  *
  724.  *  d = 1/9a,
  725.  *
  726.  * the routine performs up to 10 Newton iterations to find the
  727.  * root of igamc(a,x) - y = 0.
  728.  *
  729.  *
  730.  * ACCURACY:
  731.  *
  732.  * Tested for a ranging from 0.5 to 30 and x from 0 to 0.5.
  733.  *
  734.  *                      Relative error:
  735.  * arithmetic   domain     # trials      peak         rms
  736.  *    DEC       0,0.5         3400       8.8e-16     1.3e-16
  737.  *    IEEE      0,0.5        10000       1.1e-14     1.0e-15
  738.  *
  739.  */
  740.  
  741. static DBL igami(a, y0)
  742. DBL a, y0;
  743. {
  744.   DBL d, y, x0, lgm;
  745.   int i;
  746.  
  747. /* approximation to inverse function */
  748.   d = 1.0 / (9.0 * a);
  749.   y = (1.0 - d - ndtri(y0) * sqrt(d));
  750.  
  751.   x0 = a * y * y * y;
  752.  
  753.   lgm = lgam(a);
  754.  
  755.   for (i = 0; i < 10; i++)
  756.   {
  757.     if (x0 <= 0.0)
  758.     {
  759. /*
  760.       mtherr("igami", UNDERFLOW);
  761. */
  762.       return (0.0);
  763.     }
  764.  
  765.     y = igamc(a, x0);
  766.  
  767. /* compute the derivative of the function at this point */
  768.     d = (a - 1.0) * log(x0) - x0 - lgm;
  769.  
  770.     if (d < -MAXLOG)
  771.     {
  772. /*
  773.       mtherr("igami", UNDERFLOW);
  774. */
  775.       goto done;
  776.     }
  777.  
  778.     d = -exp(d);
  779.  
  780. /* compute the step to the next approximation of x */
  781.     if (d == 0.0)
  782.     {
  783.       goto done;
  784.     }
  785.  
  786.     d = (y - y0) / d;
  787.  
  788.     x0 = x0 - d;
  789.  
  790.     if (i < 3)
  791.     {
  792.       continue;
  793.     }
  794.  
  795.     if (fabs(d / x0) < 2.0 * MACHEP)
  796.     {
  797.       goto done;
  798.     }
  799.   }
  800.  
  801. done:
  802.  
  803.   return (x0);
  804. }
  805.  
  806.  
  807.  
  808. /*              ndtri.c
  809.  *
  810.  *  Inverse of Normal distribution function
  811.  *
  812.  *
  813.  *
  814.  * SYNOPSIS:
  815.  *
  816.  * DBL x, y, ndtri();
  817.  *
  818.  * x = ndtri( y );
  819.  *
  820.  *
  821.  *
  822.  * DESCRIPTION:
  823.  *
  824.  * Returns the argument, x, for which the area under the
  825.  * Gaussian probability density function (integrated from
  826.  * minus infinity to x) is equal to y.
  827.  *
  828.  *
  829.  * For small arguments 0 < y < exp(-2), the program computes
  830.  * z = sqrt( -2.0 * log(y) );  then the approximation is
  831.  * x = z - log(z)/z  - (1/z) P(1/z) / Q(1/z).
  832.  * There are two rational functions P/Q, one for 0 < y < exp(-32)
  833.  * and the other for y up to exp(-2).  For larger arguments,
  834.  * w = y - 0.5, and  x/sqrt(2pi) = w + w**3 R(w**2)/S(w**2)).
  835.  *
  836.  *
  837.  * ACCURACY:
  838.  *
  839.  *                      Relative error:
  840.  * arithmetic   domain        # trials      peak         rms
  841.  *    DEC      0.125, 1         5500       9.5e-17     2.1e-17
  842.  *    DEC      6e-39, 0.135     3500       5.7e-17     1.3e-17
  843.  *    IEEE     0.125, 1        20000       7.2e-16     1.3e-16
  844.  *    IEEE     3e-308, 0.135   50000       4.6e-16     9.8e-17
  845.  *
  846.  *
  847.  * ERROR MESSAGES:
  848.  *
  849.  *   message         condition    value returned
  850.  * ndtri domain       x <= 0        -MAXNUM
  851.  * ndtri domain       x >= 1         MAXNUM
  852.  *
  853.  */
  854.  
  855. static DBL ndtri(y0)
  856. DBL y0;
  857. {
  858.   DBL x, y, z, y2, x0, x1;
  859.   int code;
  860.  
  861.   if (y0 <= 0.0)
  862.   {
  863. /*
  864.     mtherr("ndtri", DOMAIN);
  865. */
  866.     return (-MAXNUM);
  867.   }
  868.  
  869.   if (y0 >= 1.0)
  870.   {
  871. /*
  872.     mtherr("ndtri", DOMAIN);
  873. */
  874.     return (MAXNUM);
  875.   }
  876.  
  877.   code = 1;
  878.  
  879.   y = y0;
  880.  
  881.   if (y > (1.0 - 0.13533528323661269189)) /* 0.135... = exp(-2) */
  882.   {
  883.     y = 1.0 - y;
  884.     code = 0;
  885.   }
  886.  
  887.   if (y > 0.13533528323661269189)
  888.   {
  889.     y = y - 0.5;
  890.     y2 = y * y;
  891.     x = y + y * (y2 * polevl(y2, P0, 4) / p1evl(y2, Q0, 8));
  892.     x = x * s2pi;
  893.  
  894.     return (x);
  895.   }
  896.  
  897.   x = sqrt(-2.0 * log(y));
  898.   x0 = x - log(x) / x;
  899.  
  900.   z = 1.0 / x;
  901.  
  902.   if (x < 8.0)  /* y > exp(-32) = 1.2664165549e-14 */
  903.   {
  904.     x1 = z * polevl(z, P1, 8) / p1evl(z, Q1, 8);
  905.   }
  906.   else
  907.   {
  908.     x1 = z * polevl(z, P2, 8) / p1evl(z, Q2, 8);
  909.   }
  910.  
  911.   x = x0 - x1;
  912.  
  913.   if (code != 0)
  914.   {
  915.     x = -x;
  916.   }
  917.  
  918.   return (x);
  919. }
  920.  
  921.  
  922.  
  923. /*              polevl.c
  924.  *              p1evl.c
  925.  *
  926.  *  Evaluate polynomial
  927.  *
  928.  *
  929.  *
  930.  * SYNOPSIS:
  931.  *
  932.  * int N;
  933.  * DBL x, y, coef[N+1], polevl[];
  934.  *
  935.  * y = polevl( x, coef, N );
  936.  *
  937.  *
  938.  *
  939.  * DESCRIPTION:
  940.  *
  941.  * Evaluates polynomial of degree N:
  942.  *
  943.  *                     2          N
  944.  * y  =  C  + C x + C x  +...+ C x
  945.  *        0    1     2          N
  946.  *
  947.  * Coefficients are stored in reverse order:
  948.  *
  949.  * coef[0] = C  , ..., coef[N] = C  .
  950.  *            N                   0
  951.  *
  952.  *  The function p1evl() assumes that coef[N] = 1.0 and is
  953.  * omitted from the array.  Its calling arguments are
  954.  * otherwise the same as polevl().
  955.  *
  956.  *
  957.  * SPEED:
  958.  *
  959.  * In the interest of speed, there are no checks for out
  960.  * of bounds arithmetic.  This routine is used by most of
  961.  * the functions in the library.  Depending on available
  962.  * equipment features, the user may wish to rewrite the
  963.  * program in microcode or assembly language.
  964.  *
  965.  */
  966.  
  967. static DBL polevl(x, coef, N)
  968. DBL x;
  969. DBL coef[];
  970. int N;
  971. {
  972.   DBL ans;
  973.   int i;
  974.   DBL *p;
  975.  
  976.   p = coef;
  977.   ans = *p++;
  978.   i = N;
  979.  
  980.   do
  981.   {
  982.     ans = ans * x + *p++;
  983.   }
  984.   while (--i);
  985.  
  986.   return (ans);
  987. }
  988.  
  989. /*              p1evl() */
  990. /*                                          N
  991.  * Evaluate polynomial when coefficient of x  is 1.0.
  992.  * Otherwise same as polevl.
  993.  */
  994.  
  995. static DBL p1evl(x, coef, N)
  996. DBL x;
  997. DBL coef[];
  998. int N;
  999. {
  1000.   DBL ans;
  1001.   DBL *p;
  1002.   int i;
  1003.  
  1004.   p = coef;
  1005.   ans = x + *p++;
  1006.   i = N - 1;
  1007.  
  1008.   do
  1009.   {
  1010.     ans = ans * x + *p++;
  1011.   }
  1012.   while (--i);
  1013.  
  1014.   return (ans);
  1015. }
  1016.  
  1017.